package love.lemoncat.websocket;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.extern.slf4j.Slf4j;
import love.lemoncat.service.MockDevService;
import love.lemoncat.websocket.msg.RequestMsg;
import love.lemoncat.websocket.msg.ResponseMsg;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@ChannelHandler.Sharable
@Component
public class TextChannelHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
    @Autowired
    private MockDevService mockService;
    private static Map<Channel, ClientHolder> cache = new ConcurrentHashMap();

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        cache.put(ctx.channel(), new ClientHolder(ctx.channel()));
        TextWebSocketFrame msg = new TextWebSocketFrame("服务器欢迎你");
        ctx.channel().writeAndFlush(msg);
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
        RequestMsg requestMsg = new RequestMsg();
        requestMsg = requestMsg.decodeTextFrame(msg);
        ClientHolder clientHolder = cache.get(ctx.channel());
        clientHolder.handleRequest(requestMsg, mockService);
        log.info("{}", cache);
    }


    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        cache.remove(ctx.channel());
        ctx.close();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("{}", cause);
        cache.remove(ctx.channel());
        ctx.close();
    }

    public void send(ResponseMsg resp){
        for (ClientHolder clientHolder : cache.values()) {
            clientHolder.handleResponse(resp);
        }
    }
}
